/**
 * 键盘漫游包括方向，控制键{
 *     W-前
 *     S-后
 *     A-左
 *     D-右
 *     Q-向上
 *     E-向下
 * }
 */
import * as Cesium from 'cesium';
let that:any=null;
class KeyPath2{
    _viewer:any;
    flags:any;
    handler:any;
    constructor(viewer:any) {
        this._viewer=viewer;
        // 2.初始化相机漫游的标记
        this.flags = {
            looking: false, // 是否正在用鼠标调整视角
            startPosition: null, // 鼠标指针开始移动位置
            endPosition: null, // 鼠标指针停止移动位置
            moveForward: false, // 是否向前移动
            moveBackward: false, // 是否向后移动
            moveLeft: false, // 是否向左移动
            moveRight: false, // 是否向右移动
            moveUp: false, // 是否向上移动
            moveDown: false, // 是否向下移动
        };
        this.handler=null;
    }
    /**
     * 进入键盘鼠标漫游模式
     */
     startRunning() {
         let _this=this;
         let scene=this._viewer.scene;
        // 1.禁用默认相机操作模式
        scene.screenSpaceCameraController.enableRotate = false;
        scene.screenSpaceCameraController.enableTranslate = false;
        scene.screenSpaceCameraController.enableZoom = false;
        scene.screenSpaceCameraController.enableTilt = false;
        scene.screenSpaceCameraController.enableLook = false;
        // 3.添加鼠标监听事件
        this.handler = new Cesium.ScreenSpaceEventHandler(this._viewer.canvas);
        // 左键按下
        this.handler.setInputAction((movement:any) => {
            _this.flags.looking = true;
            _this.flags.startPosition = Cesium.Cartesian3.clone(movement.position);
            _this.flags.endPosition = Cesium.Cartesian3.clone(movement.position);
        }, Cesium.ScreenSpaceEventType.LEFT_DOWN);
        // 鼠标移动
        this.handler.setInputAction((movement:any) => {
            _this.flags.endPosition = movement.endPosition;
        }, Cesium.ScreenSpaceEventType.MOUSE_MOVE);
        // 左键弹起
        this.handler.setInputAction(() => {
            _this.flags.looking = false;
        }, Cesium.ScreenSpaceEventType.LEFT_UP);

        // 4.添加键盘监听事件
        // 键盘按下事件
        document.addEventListener('keydown', this.keyDown, false);
        // 键盘弹起事件
        document.addEventListener('keyup', this.keyUp, false);
        that=this;
        // 5.添加渲染事件
        this._viewer.clock.onTick.addEventListener(this.renderEvent);
    }



    /**
     * 退出键盘鼠标漫游模式
     */
     endRunning() {
        // 1.移除鼠标监听事件
        if (this.handler) {
            this.handler.destroy();
            this.handler = null;
        }

        // 2.移除键盘监听事件
        document.removeEventListener('keydown', this.keyDown, false);
        document.removeEventListener('keyup', this.keyUp, false);

        // 3.移除渲染事件
        this._viewer.clock.onTick.removeEventListener(this.renderEvent);
        let scene=this._viewer.scene;
        // 4.启用默认相机操作模式
        scene.screenSpaceCameraController.enableRotate = true;
        scene.screenSpaceCameraController.enableTranslate = true;
        scene.screenSpaceCameraController.enableZoom = true;
        scene.screenSpaceCameraController.enableTilt = true;
        scene.screenSpaceCameraController.enableLook = true;
    }


    /**
     * 键盘按下
     */
     keyDown(event:any) {
        let flagName = innerFun.getFlagFromKeyCode(event.keyCode);
        if (typeof flagName !== 'undefined') {
            that.flags[flagName] = true;
        }
    }

    /**
     * 键盘弹起
     */
     keyUp(event:any) {
        let flagName = innerFun.getFlagFromKeyCode(event.keyCode);
        if (typeof flagName !== 'undefined') {
            that.flags[flagName] = false;
        }
    }

    /**
     * 渲染函数
     */
     renderEvent() {
         let camera=that._viewer.camera;
        // 镜头转向
        if (that.flags.looking) {
            let width = that._viewer.canvas.clientWidth;
            let height = that._viewer.canvas.clientHeight;
            let lookFactor = 0.05; // 镜头转向系数，系数越大约灵敏，此处取0.05比较适中
            let x = (that.flags.endPosition.x - that.flags.startPosition.x) / width;
            let y = -(that.flags.endPosition.y - that.flags.startPosition.y) / height;
            // 计算出x,y之后，有两种方式实现镜头，经过测试感觉方式 1更流畅
            // 方式 1
            camera.lookRight(x * lookFactor);
            camera.lookUp(y * lookFactor);
            // 方式 2
            // camera.setView({
            //   orientation: {
            //     heading: camera.heading + x * lookFactor,
            //     pitch: camera.pitch + y * lookFactor,
            //     roll: 0.0,
            //   },
            // });
        }
        // 根据高度来决定镜头移动的速度
        let cameraHeight = that._viewer.scene.globe.ellipsoid.cartesianToCartographic(camera.position).height;
        let moveRate = cameraHeight / 100.0;
        if (that.flags.moveForward) {
            camera.moveForward(moveRate);
        }
        if (that.flags.moveBackward) {
            camera.moveBackward(moveRate);
        }
        if (that.flags.moveUp) {
            camera.moveUp(moveRate);
        }
        if (that.flags.moveDown) {
            camera.moveDown(moveRate);
        }
        if (that.flags.moveLeft) {
            camera.moveLeft(moveRate);
        }
        if (that.flags.moveRight) {
            camera.moveRight(moveRate);
        }
    }
}
export default KeyPath2;

const innerFun={
    /**
     * 从键盘码获取flag标记
     */
    getFlagFromKeyCode(keyCode:any) {
        switch (keyCode) {
            case 'W'.charCodeAt(0):
                return 'moveForward';
            case 'S'.charCodeAt(0):
                return 'moveBackward';
            case 'Q'.charCodeAt(0):
                return 'moveUp';
            case 'E'.charCodeAt(0):
                return 'moveDown';
            case 'D'.charCodeAt(0):
                return 'moveRight';
            case 'A'.charCodeAt(0):
                return 'moveLeft';
            default:
                return undefined;
        }
    }
}
